/**
 * Copyright (C) 2005-2009 Alfresco Software Limited.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

 * As a special exception to the terms and conditions of version 2.0 of 
 * the GPL, you may redistribute this Program in connection with Free/Libre 
 * and Open Source Software ("FLOSS") applications as described in Alfresco's 
 * FLOSS exception.  You should have recieved a copy of the text describing 
 * the FLOSS exception, and it is also available here: 
 * http://www.alfresco.com/legal/licensing
 */
 
if (typeof GWI == "undefined" || !GWI){
	var GWI = {};
} 
GWI.dashlet = GWI.dashlet || {};  

/**
 * AddRun module
 *
 * A dialog for adding runs
 *
 * @namespace GWI.dashlet
 * @class GWI.dashlet.AddRun
 */
(function()
{
   
   var Dom = YAHOO.util.Dom,
      Event = YAHOO.util.Event,
      Element = YAHOO.util.Element,
      KeyListener = YAHOO.util.KeyListener;
   
   /**
    * Add Run constructor.
    *
    * @param htmlId {string} A unique id for this component
    * @return {GWI.dashlet.AddRun} 
    * @constructor
    */
   GWI.dashlet.AddRun = function(containerId)
   {
      var instance = Alfresco.util.ComponentManager.get(this.id);
      if (instance !== null)
      {
         throw new Error("An instance of GWI.dashlet.AddRun already exists.");
      }

      GWI.dashlet.AddRun.superclass.constructor.call(this, "GWI.dashlet.AddRun", containerId, ["button", "container", "connection", "selector", "json"]);

      return this;
   };

   YAHOO.extend(GWI.dashlet.AddRun, Alfresco.component.Base,
   {
	  /**
	   * Publisher
	   * @property publisher
	   * @type object
	   */
	  publisher : null,
      /**
       * Shows the CreteSite dialog to the user.
       *
       * @method show
       */
      show: function AddRun_show()
      {
		//Init publisher
		this.publisher = new function () {
			this.sendMessage = function (msg) {
				YAHOO.util.Event.publish(
					"SHOW_USER_DETAILS_CHANNEL",
					{message: msg});
			}
		};	 
        /**
         * Load the gui from the server and let the templateLoaded() method
         * handle the rest.
         */
        Alfresco.util.Ajax.request(
        {
           url: Alfresco.constants.URL_SERVICECONTEXT + "be/gwi/components/dashlets/run-challenge/addRun",
           dataObj:
           {
              htmlid: this.id
           },
           successCallback:
           {
              fn: this.onTemplateLoaded,
              scope: this
           },
           execScripts: true,
           failureMessage: "Could not load create site template"
        });
      },

      /**
       * Called when the AddRun html template has been returned from the server.
       * Creates the YUI gui objects such as buttons and a panel and shows it.
       *
       * @method onTemplateLoaded
       * @param response {object} a Alfresco.util.Ajax.request response object 
       */
      onTemplateLoaded: function AddRun_onTemplateLoaded(response)
      {
         // Inject the template from the XHR request into a new DIV element
         var containerDiv = document.createElement("div");
         containerDiv.innerHTML = response.serverResponse.responseText;

         // The panel is created from the HTML returned in the XHR request, not the container
         var panelDiv = Dom.getFirstChild(containerDiv);

         this.widgets.panel = Alfresco.util.createYUIPanel(panelDiv);

         // Create the cancel button
         this.widgets.cancelButton = Alfresco.util.createYUIButton(this, "cancel-button", this.onCancelButtonClick);

         // Create the ok button, the forms runtime will handle when its clicked
         this.widgets.okButton = Alfresco.util.createYUIButton(this, "ok-button", null,
         {
            type: "submit"
         });
         
         // Configure the forms runtime
         var addRunForm = new Alfresco.forms.Form(this.id + "-form");

         // Balloon validation messages
         this.widgets.balloons = {};

         var elDistance = Dom.get(this.id + "-runDistance"),
            elRunType = Dom.get(this.id + "-runType"), 
            elRunDate = Dom.get(this.id + "-runDate"),
            elRunUrl = Dom.get(this.id + "-runUrl");

         addRunForm.addValidation(elDistance, Alfresco.forms.validation.mandatory, null, "keyup", this.msg("validation-hint.mandatory"));
         addRunForm.addValidation(elDistance, Alfresco.forms.validation.number, null, "keyup", this.msg("validation-hint.number"));
         addRunForm.addValidation(elRunType, Alfresco.forms.validation.mandatory, null, "keyup", this.msg("validation-hint.mandatory"));
         addRunForm.addValidation(elDistance, Alfresco.forms.validation.number, null, "blur", this.msg("validation-hint.number"));
         
         this.widgets.balloons[this.id + "-runDistance"] = Alfresco.util.createBalloon(elDistance);

         // Remove the balloon after the text box has lost focus. This prevents multiple validation balloons overlapping.
         Event.addListener(elDistance, "blur", function AddRun_distance_blur()
         {
            if (this.widgets.balloons[this.id + "-runDistance"])
            {
               this.widgets.balloons[this.id + "-runDistance"].hide();
            }
         }, this, true);

         
         // Override Forms Runtime's error handling
         var scope = this;
         addRunForm.addError = function AddRun_form_addError(msg, field)
         {
            if (scope.widgets.panel.cfg.getProperty("visible"))
            {
               var balloon = scope.widgets.balloons[field.id];
               if (balloon)
               {
                  balloon.html(msg);
                  balloon.show();
               }
            }
         };

         // The ok button is the submit button, and it should be enabled when the form is ready
         addRunForm.setShowSubmitStateDynamically(true, true);
         addRunForm.setSubmitElements(this.widgets.okButton);
         addRunForm.doBeforeFormSubmit =
         {
            fn: function()
            {
               var formEl = Dom.get(this.id + "-form");
               formEl.attributes.action.nodeValue = Alfresco.constants.PROXY_URI + "gwi/run/addRun.json"; 
               
               this.widgets.okButton.set("disabled", true);
               this.widgets.cancelButton.set("disabled", true);
               
               this.widgets.panel.hide();
               this.widgets.feedbackMessage = Alfresco.util.PopupManager.displayMessage(
               {
                  text: Alfresco.util.message("message.creating", this.name),
                  spanClass: "wait",
                  displayTime: 0
               });
            },
            obj: null,
            scope: this
         };

         // Submit as an ajax submit (not leave the page), in json format
         addRunForm.setAJAXSubmit(true,
         {
            successCallback:
            {
               fn: this.onAddRunSuccess,
               scope: this               
            },
            failureCallback:
            {
               fn: this.onAddRunFailure,
               scope: this
            }
         });
         addRunForm.setSubmitAsJSON(true);
         // We're in a popup, so need the tabbing fix
         addRunForm.applyTabFix();
         addRunForm.init();

         // Show the panel
         this._showPanel();
      },

      /**
       * Converts a user-entered string into a "readable" safe URL by stripping characters
       *
       * @method safeURL
       * @param text {string} The string to convert
       * @return {string} Safe and readable URL
       */
      safeURL: function AddRun_safeURL(text)
      {
         // Strip unwanted characters and trim leading and trailing spaces
         text = YAHOO.lang.trim(text.replace(/[^0-9a-zA-Z\-\s]/g, ""));
         // Replace remaining spaces with dash & convert the whole string to lower case
         text = text.replace(/\s+/g, "-").toLowerCase();

         return text;
      },
      
      /**
       * Called when user clicks on the cancel button.
       * Closes the AddRun panel.
       *
       * @method onCancelButtonClick
       * @param type
       * @param args
       */
      onCancelButtonClick: function AddRun_onCancelButtonClick(type, args)
      {
         for (var index in this.widgets.balloons)
         {
            if (this.widgets.balloons.hasOwnProperty(index))
            {
               this.widgets.balloons[index].hide();
            }
         }

         // Reset the form fields
         try
         {
            Dom.get(this.id + "-runDistance").value = "";
            Dom.get(this.id + "-runType").setSelectedIndex = 0;
            Dom.get(this.id + "-runUrl").value = "";
         }
         catch(e)
         {
         }

         this.widgets.panel.hide();
      },

      /**
       * Called when a run has been succesfully added on the server.
       *
       * @method onAddRunSuccess
       * @param response
       */
      onAddRunSuccess: function AddRun_onAddRunSuccess(response)
      {
    	  //TODO publish event to refresh Run view
    	  this.publisher.sendMessage("");
    	  this.widgets.feedbackMessage.destroy();
      },

      /**
       * Called when a site failed to be created.
       *
       * @method onAddRunFailure
       * @param response
       */
      onAddRunFailure: function AddRun_onAddRunFailure(response)
      {
    	  this._adjustGUIAfterFailure(response);
      },

      /**
       * Helper method that restores the gui and displays an error message.
       *
       * @method _adjustGUIAfterFailure
       * @param response
       */
      _adjustGUIAfterFailure: function AddRun__adjustGUIAfterFailure(response)
      {
         this.widgets.feedbackMessage.destroy();
         this.widgets.okButton.set("disabled", false);
         this.widgets.cancelButton.set("disabled", false);
         this.widgets.panel.show();
         var text = Alfresco.util.message("message.failure", this.name);
         // Special case for (potential) private site name clash
         if (response.serverResponse.status === 403)
         {
            // User does not have permissions to create the site
            text = Alfresco.util.message("error.noPermissions", this.name);
         }
         else if (response.json.message)
         {
            var tmp = Alfresco.util.message(response.json.message, this.name);
            text = tmp ? tmp : text;
         }
         Alfresco.util.PopupManager.displayPrompt(
         {
            title: Alfresco.util.message("message.failure", this.name), 
            text: text
         });
      },

      /**
       * Prepares the gui and shows the panel.
       *
       * @method _showPanel
       * @private
       */
      _showPanel: function AddRun__showPanel()
      {
         // Show the upload panel
         this.widgets.panel.show();

         // Firefox insertion caret fix
         Alfresco.util.caretFix(this.id + "-form");

         // Register the ESC key to close the dialog
         var escapeListener = new KeyListener(document,
         {
            keys: KeyListener.KEY.ESCAPE
         },
         {
            fn: function(id, keyEvent)
            {
               this.onCancelButtonClick();
            },
            scope: this,
            correctScope: true
         });
         escapeListener.enable();

         // Set the focus on the first field
         Dom.get(this.id + "-runDistance").focus();
      }
   });
})();

GWI.dashlet.getAddRunInstance = function()
{
   var instanceId = "gwi-addRun-instance";
   return Alfresco.util.ComponentManager.get(instanceId) || new GWI.dashlet.AddRun(instanceId);
};